package com.huawei.esdk.uc.sametime.uccallbackimpl;

import org.apache.log4j.Logger;
import org.eclipse.swt.widgets.Display;

import com.huawei.esdk.uc.jna.UCService;
import com.huawei.esdk.uc.jna.Constants.ContactAvailability;
import com.huawei.esdk.uc.jna.callback.AVSessAddedCB;
import com.huawei.esdk.uc.jna.callback.AVSessionClosedCB;
import com.huawei.esdk.uc.jna.callback.AVSessionConnectedCB;
import com.huawei.esdk.uc.jna.struct.STAudioVideoParam;
import com.huawei.esdk.uc.jna.struct.STMsgAVSessionClosedParam;
import com.huawei.esdk.uc.jna.util.StringUtil;
import com.huawei.esdk.uc.sametime.ConstantsDefines.CallMode;
import com.huawei.esdk.uc.sametime.ConstantsDefines.CallStatus;
import com.huawei.esdk.uc.sametime.international.Messages;
import com.huawei.esdk.uc.sametime.services.UCCallService;
import com.huawei.esdk.uc.sametime.widgets.CallComeInPopup;
import com.huawei.esdk.uc.sametime.widgets.EsdkUCConvWindow;
import com.ibm.collaboration.realtime.people.PeopleUtil;

/**
 * 呼叫回调的实现类 现在呼叫回调类和特定功能做了强耦合,后面需考虑在内部维护一个特定vector,存储响应的回调处理类,这样就实现了简单的监听者模式
 * @author lwx169831
 * 
 */
public class UCVoiceCallBackImpl
{

    private Logger logger = Logger.getLogger(UCVoiceCallBackImpl.class);

    private static UCVoiceCallBackImpl instance = new UCVoiceCallBackImpl();

    private AVSessAddedCB sessAddedCB;

    private AVSessionConnectedCB sessionConnectedCB;

    private AVSessionClosedCB sessionClosedCB;

    public static UCVoiceCallBackImpl getInstance()
    {
        return instance;
    }

    private UCVoiceCallBackImpl()
    {
        sessAddedCB = new AVSessAddedCB()
        {
            @Override
            public void callBack(STAudioVideoParam avParam)
            {
                logger.debug("AVSessAddedCB | ucAcc = "
                        + StringUtil.bytesToString(avParam.ucAcc)
                        + ", accountType = " + avParam.accountType
                        + ", callMode = " + avParam.callMode + ", isvideo = "
                        + avParam.isvideo);
                addCallBack(avParam);
            }
        };

        sessionConnectedCB = new AVSessionConnectedCB()
        {
            @Override
            public void callBack()
            {
                logger.debug("AVSessionConnectedCB");
                connectedCallBack();
            }
        };

        sessionClosedCB = new AVSessionClosedCB()
        {
            @Override
            public void callBack(STMsgAVSessionClosedParam avParam)
            {
                logger.debug("AVSessionClosedCB | AVSessionId = "
                        + StringUtil.bytesToString(avParam.AVSessionId)
                        + ", callerUri = " + avParam.getCallerUri()
                        + ", reason = " + avParam.getReason());
                closedCallBack(avParam);
            }
        };
    }

    private void addCallBack(final STAudioVideoParam avParam)
    {
        UCCallService.setCallMode(CallMode.callIn);
        UCCallService.setCallStatus(CallStatus.calling);
        ShowCallComePopJob showCallComePopJob = new ShowCallComePopJob(avParam);
        Display.getDefault().syncExec(showCallComePopJob);

        // 发布自己的状态
        UCService.getInstance().UC_SDK_PubSelfStatus(ContactAvailability.Busy,
                "");
        PeopleUtil.getLocalPerson().refreshStatus();
    }

    private void connectedCallBack()
    {
        UCCallService.setCallStatus(CallStatus.connected);
        ShowCallWindowJob showCallWindowJob = new ShowCallWindowJob();
        Display.getDefault().syncExec(showCallWindowJob);

        EsdkUCConvWindow.getInstance().callStart();
        SetStatusTipJob setStatusTipJob = new SetStatusTipJob();
        Display.getDefault().syncExec(setStatusTipJob);
    }

    private void closedCallBack(STMsgAVSessionClosedParam avParam)
    {
        CloseCallResourceJob closeCallJob = new CloseCallResourceJob();
        Display.getDefault().syncExec(closeCallJob);
    }

    public AVSessAddedCB getAddedCB()
    {
        return sessAddedCB;
    }

    public AVSessionConnectedCB getConnectedCB()
    {
        return sessionConnectedCB;
    }

    public AVSessionClosedCB getClosedCB()
    {
        return sessionClosedCB;
    }

    private static class ShowCallComePopJob implements Runnable
    {
        private STAudioVideoParam audioVideoParam;

        public ShowCallComePopJob(STAudioVideoParam audioVideoParam)
        {
            this.audioVideoParam = audioVideoParam;
        }

        @Override
        public void run()
        {
            CallComeInPopup.getInstance().showComeInPopup(this.audioVideoParam);
        }
    }

    private static class ShowCallWindowJob implements Runnable
    {
        @Override
        public void run()
        {
            CallComeInPopup.getInstance().showCallWindowForPhone();
        }
    }

    private static class SetStatusTipJob implements Runnable
    {
        @Override
        public void run()
        {
            EsdkUCConvWindow.getInstance().setStatusTip(
                    Messages.EsdkUCConvWindow_CALL_CONNECTED);
        }
    }

    private static class CloseCallResourceJob implements Runnable
    {
        @Override
        public void run()
        {
            CallComeInPopup.getInstance().closeComeInPopup();
            EsdkUCConvWindow.getInstance().closeContents();
        }
    }
}